package fag.core.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import fag.core.collision.Hitbox;
import fag.core.geometry.Rectangle2D;

public class Animation implements Cloneable, Serializable {

	String name;
	List<Frame> frames;
	double actualTime;
	int actualFrame;
	double endTime;
	double speed;
	boolean loop;
	
	private static final long serialVersionUID = -1792859844592715379L;
	private boolean alreadyLoopOnce;
	
	
	public Animation() {
		
		name = "Animation inconnue";
		frames = new ArrayList<Frame>();
		actualTime = 0;
		actualFrame = 0;
		endTime = 0;
		speed = 1;
		loop = true;
		alreadyLoopOnce = false;
	}
	
	public Animation(String s) {
		
		name = s;
		frames = new ArrayList<Frame>();
		actualTime = 0;
		actualFrame = 0;
		endTime = 0;
		speed = 1;
		loop = true;
		alreadyLoopOnce = false;
	}
	
	public Animation clone() {

		Animation animation = null;
		
		try {
			animation = (Animation) super.clone();
		}
		
		catch (CloneNotSupportedException cloneNotSupportedException) {
			cloneNotSupportedException.printStackTrace();
		}
		
		return animation;
	}
	
	public void reset() {
		
		actualTime = 0;
		actualFrame = 0;
		alreadyLoopOnce = false;
	}
	
	public void forward(double ms) {

		
		if(endTime == 0) {
			
			actualFrame = -1;
		}
		
		actualTime += speed * ms;
		
		if(actualTime > endTime) {
			
			actualTime -= endTime;
			alreadyLoopOnce = true;
		}
		
		if((loop == false) && (alreadyLoopOnce == true)) {
			
			return;
		}
		
		int cpt = 0;
		
		for(int i=0; i<frames.size() ; i++) {
			
			if(actualTime <= frames.get(i).duration+cpt) {
				
				
				actualFrame = i;
				return;
			}
			else {
				
				cpt += frames.get(i).duration;
			}
		}
	}
	
	public Sprite getCurrentSprite() {
		
		return frames.get(actualFrame).sprite;
	}
	
	/**
	 * Accesseur de la boîte englobante de la frame actuelle.
	 * @return La boîte englobante de la frame actuelle.
	 */
	public Rectangle2D getCurrentBounds() {
		 
		return frames.get(actualFrame).getBounds();
	}
	
	/**
	 * Accesseur de la liste des boîtes de collisions courantes.
	 * @return La liste des boîtes de collisions pour la frame actuelle de l'animation.
	 */
	public Hitbox getCurrentHitbox() {
	
		return frames.get(actualFrame).hitbox;
	}
	
	public void setSpeed(double s) {
		
		speed = s;
	}
	
	public void setLoop(boolean b) {
		
		reset();
		loop = b;
	}
	
	public void addFrameAtEnd(Frame f) {
		
		endTime += f.duration;
		frames.add(f);
	}

	public double getSpeed() {
		
		return speed;
	}
	
	public boolean isLooping() {
		
		return loop;
	}
	
	public String getName() {
		
		return name;
	}

	public void setName(String s) {
		
		name = s;
	}
}
